﻿namespace TanHungViet.Web.Models
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using log4net;

    public class ContentRepository
    {
        private static ILog _logger = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
        private DBTanHungVietEntities _db;

        public ContentRepository(DBTanHungVietEntities entity)
        {
            _db = entity;
        }

        public List<Content> GetListContentForHomePage(string cultureInfo)
        {
            try
            {
                List<int> projectIDs = (from b in _db.ProjectContent
                                        select b.ContentID).ToList<int>();

                List<Content> contents = (from b in _db.Content
                                          join n in _db.ProjectContent
                                          on b.ContentID equals n.ContentID
                                          where n.InHomePage == true
                                          select b).ToList<Content>();

                if (contents == null)
                {
                    _logger.Warn("Khong ton tai project nao trong db");
                    return null;
                }

                for (int i = 0; i < contents.Count; i++)
                {
                    Content content = contents[i];
                    if (!projectIDs.Contains(content.ContentID))
                    {
                        contents.RemoveAt(i);
                        i--;
                    }
                }

                foreach (var content in contents)
                {
                    var project = _db.ProjectContent.FirstOrDefault(b => b.ContentID == content.ContentID);
                    if (project != null)
                    {
                        content.Investor = project.Investor;
                        content.Address = project.Address;
                        content.Designer = project.Designer;
                    }

                    var language = _db.Language.FirstOrDefault(b => b.LanguageCode.Equals(cultureInfo));
                    if (language == null)
                    {
                        _logger.WarnFormat("Khong tim thay ngon ngu voi cultureInfo={0}", cultureInfo);
                        content.ContentTitle = string.Empty;
                    }
                    else
                    {
                        var contentDetal = _db.ContentDetail.FirstOrDefault(b => b.ContentID == content.ContentID && b.LanguageID == language.LanguageID);
                        if (contentDetal == null)
                        {
                            _logger.Warn("Khong tim thay du lieu trong ContentDetail table");
                            content.ContentTitle = string.Empty;
                        }
                        else
                        {
                            content.ContentTitle = contentDetal.ContentTitle;
                            content.BriefDescrip = contentDetal.BriefDescription;
                        }
                    }
                }

                return contents;
            }
            catch (Exception ex)
            {
                _logger.Error(ex);
                throw new ArgumentException(ex.Message);
            }
        }

        public IQueryable<Content> GetListContentByParentCode(string code, string cultureInfo)
        {
            try
            {
                var parent = _db.Content.FirstOrDefault(b => b.ContentCode == code);
                if (parent == null)
                {
                    _logger.WarnFormat("Khong co content chua contentCode={0}", code);
                    return null;
                }

                var contents = from b in _db.Content
                               where b.ContentParent == parent.ContentID
                               select b;
                if (contents == null)
                {
                    _logger.WarnFormat("Content chua contentCode={0} khong co content con", code);
                    return null;
                }
                foreach (var content in contents)
                {
                    var project = _db.ProjectContent.FirstOrDefault(b => b.ContentID == content.ContentID);
                    if (project != null)
                    {
                        content.Investor = project.Investor;
                        content.Address = project.Address;
                        content.Designer = project.Designer;
                    }

                    var language = _db.Language.FirstOrDefault(b => b.LanguageCode.Equals(cultureInfo));
                    if (language == null)
                    {
                        _logger.WarnFormat("Khong tim thay ngon ngu voi cultureInfo={0}", cultureInfo);
                        content.ContentTitle = string.Empty;
                    }
                    else
                    {
                        var contentDetal = _db.ContentDetail.FirstOrDefault(b => b.ContentID == content.ContentID && b.LanguageID == language.LanguageID);
                        if (contentDetal == null)
                        {
                            _logger.Warn("Khong tim thay du lieu trong ContentDetail table");
                            content.ContentTitle = string.Empty;
                        }
                        else
                        {
                            content.ContentTitle = contentDetal.ContentTitle;
                            content.BriefDescrip = contentDetal.BriefDescription;
                        }
                    }
                }

                return contents;
            }
            catch (Exception ex)
            {
                _logger.Error(ex);
                throw new ArgumentException(ex.Message);
            }
        }

        public Content GetParentByContentCode(string code, string cultureInfo)
        {
            try
            {
                var content = _db.Content.FirstOrDefault(b => b.ContentCode == code);
                if (content == null)
                {
                    _logger.WarnFormat("Khong co content chua contentCode={0}", code);
                    return null;
                }

                var parent = _db.Content.FirstOrDefault(b => b.ContentID == content.ContentParent);
                if (parent == null)
                {
                    _logger.WarnFormat("Khong co content chua contentCode={0}", code);
                    return null;
                }

                return GetContentByCode(parent.ContentCode, cultureInfo);
            }
            catch (Exception ex)
            {
                _logger.Error(ex);
                throw new ArgumentException(ex.Message);
            }
        }

        public Content GetContentByCode(string code, string cultureInfo)
        {
            try
            {
                var content = _db.Content.FirstOrDefault(b => b.ContentCode == code);
                if (content == null)
                {
                    _logger.WarnFormat("Khong tim thay content voi code={0}", code);
                    return null;
                }

                var language = _db.Language.FirstOrDefault(b => b.LanguageCode.Equals(cultureInfo));
                if (language == null)
                {
                    _logger.WarnFormat("Khong tim thay ngon ngu voi cultureInfo={0}", cultureInfo);
                    return content;
                }

                var detail = _db.ContentDetail.FirstOrDefault(b => b.ContentID == content.ContentID && b.LanguageID == language.LanguageID);
                if (detail == null)
                {
                    _logger.Warn("Khong tim thay du lieu trong ContentDetail table");
                    return content;
                }
                content.ContentTitle = detail.ContentTitle;
                content.BriefDescrip = detail.BriefDescription;
                content.ContentDetail = detail.ContentDetail1;

                var project = _db.ProjectContent.FirstOrDefault(b => b.ContentID == content.ContentID);
                if (project == null)
                {
                    _logger.Warn("Khong tim thay du lieu trong Project table");
                    return content;
                }
                content.Investor = project.Investor;
                content.Address = project.Address;
                content.Designer = project.Designer;

                return content;
            }
            catch (Exception ex)
            {
                _logger.Error(ex);
                throw new ArgumentException(ex.Message);
            }
        }

        public IQueryable<Content> GetListContentByType(string codeType)
        {
            try
            {
                _logger.InfoFormat("Begin GetListContentByType({0})", codeType);

                var idType = _db.Content.FirstOrDefault(b => b.ContentCode == codeType);
                if (idType == null)
                    return null;

                var list = from b in _db.Content
                           where b.ContentParent == idType.ContentID
                           select b;

                _logger.Info("End GetListContentByType ....");
                return list;
            }
            catch (Exception ex)
            {
                _logger.Error(ex);
                throw new ArgumentException(ex.Message);
            }
        }

        public IQueryable<Content> GetListContentDetailByType(string codeType)
        {
            try
            {
                _logger.InfoFormat("Begin GetListContentDetailByType({0})", codeType);

                var list = codeType != "none" ? GetListContentByType(codeType)
                    : (from b in _db.Content
                       where b.ContentParent != 0
                       select b);
                if (list == null)
                    return null;

                foreach (var item in list)
                {
                    var tempVN = _db.ContentDetail.FirstOrDefault(
                        b => b.ContentID == item.ContentID
                            && b.LanguageID == 1);

                    var tempEN = _db.ContentDetail.FirstOrDefault(
                        b => b.ContentID == item.ContentID
                            && b.LanguageID == 2);

                    if (tempVN == null)
                        _logger.Error("Content has no detail");
                    else
                    {
                        item.ContentTitle = tempVN.ContentTitle;
                        item.ContentTitle2 = tempEN != null ? tempEN.ContentTitle : string.Empty;
                    }


                    var project = _db.ProjectContent.FirstOrDefault(b => b.ContentID == item.ContentID);
                    if (project == null)
                        _logger.Info("Content is news, not Project");
                    else
                    {
                        item.Investor = project.Investor;
                        item.Address = project.Address;
                        item.Designer = project.Designer;
                        item.InHomePage = project.InHomePage ?? false;
                    }
                }

                _logger.Info("End GetListContentDetailByType ....");
                return list;
            }
            catch (Exception ex)
            {
                _logger.Error(ex);
                throw new ArgumentException(ex.Message);
            }
        }

        public Content GetFullContentByID(int id)
        {
            try
            {
                _logger.InfoFormat("Begin GetContentByID({0})", id);

                var content = _db.Content.FirstOrDefault(b => b.ContentID == id);
                if (content == null)
                    return null;

                // noi dung tieng Viet
                var contentDetail = _db.ContentDetail.FirstOrDefault(b =>
                    b.ContentID == id && b.LanguageID == 1);
                // noi dung tienh Anh
                var contentDetail2 = _db.ContentDetail.FirstOrDefault(b =>
                    b.ContentID == id && b.LanguageID == 2);

                if (contentDetail != null)
                {
                    content.ContentTitle = contentDetail.ContentTitle;
                    content.BriefDescrip = contentDetail.BriefDescription;
                    content.ContentDetail = contentDetail.ContentDetail1;
                }
                if (contentDetail2 != null)
                {
                    content.ContentTitle2 = contentDetail2.ContentTitle;
                    content.BriefDescrip2 = contentDetail2.BriefDescription;
                    content.ContentDetail2 = contentDetail2.ContentDetail1;
                }

                // la Du an
                var project = _db.ProjectContent.FirstOrDefault(b => b.ContentID == id);
                if (project != null)
                {
                    content.Investor = project.Investor;
                    content.Address = project.Address;
                    content.Designer = project.Designer;
                    content.InHomePage = project.InHomePage ?? false;
                }

                _logger.InfoFormat("End GetContentByID({0})", id);
                return content;
            }
            catch (Exception ex)
            {
                _logger.Error(ex);
                throw new ArgumentException(ex.Message);
            }
        }

        public Content GetContentByCode(string contentCode)
        {
            try
            {
                Content result = _db.Content.FirstOrDefault(b => b.ContentCode == contentCode);
                if (result == null)
                {
                    _logger.WarnFormat("Cannot find Content which has code = {0}", contentCode);
                    return null;
                }

                return result;
            }
            catch (Exception ex)
            {
                _logger.Error(ex);
                throw new ArgumentException(ex.Message);
            }
        }

        public void AddNewContent(Content newContent, string parentCode)
        {
            try
            {
                _logger.InfoFormat("Begin AddNewContent({0})", parentCode);
                Content parent = GetContentByCode(parentCode);
                if (parent == null)
                    return;
                newContent.ContentParent = parent.ContentID;
                newContent.PublishDate = DateTime.Now;

                // kiem tra content code da ton tai chua
                bool checkExistCode = true;
                do
                {
                    Content checkContent = GetContentByCode(newContent.ContentCode);
                    if (checkContent != null)
                    {
                        newContent.ContentCode += "-1";
                        _logger.InfoFormat("New content code is ({0})", newContent.ContentCode);
                    }
                    else
                        checkExistCode = false;
                } while (checkExistCode);

                _db.AddToContent(newContent);
                _db.SaveChanges();
                _logger.InfoFormat("End AddNewContent({0})", parentCode);
            }
            catch (Exception ex)
            {
                _logger.Error(ex);
                throw new ArgumentException(ex.Message);
            }
        }

        public void AddNewContentFull(Content newContent, string parentCode, bool addMenu, string link, bool hasImage, bool isProject)
        {
            try
            {
                _logger.InfoFormat("Begin AddNewContentFull({0})", parentCode);
                AddNewContent(newContent, parentCode);
                // lay contentID vua moi duoc them vao bang
                Content temp = GetContentByCode(newContent.ContentCode);
                if (temp == null)
                    return;

                if (addMenu)
                {
                    // them vao bang Menu
                    Menu newMenu = new Menu();
                    newMenu.ContentID = temp.ContentID;
                    newMenu.IsVertical = false;
                    newMenu.MenuLink = link + temp.ContentCode;
                    var contentParent = GetContentByCode(parentCode);
                    var menuParent = _db.Menu.FirstOrDefault(b => b.ContentID == contentParent.ContentID);
                    newMenu.ParentID = menuParent.MenuID;
                    var maxMenu = (from b in _db.Menu
                                   where b.ParentID == menuParent.MenuID
                                   select b).Max(b => b.MenuOrder);
                    newMenu.MenuOrder = (maxMenu.HasValue ? maxMenu.Value : (-1)) + 1;
                    _db.AddToMenu(newMenu);
                    _db.SaveChanges();
                    newMenu = _db.Menu.FirstOrDefault(b => b.ContentID == temp.ContentID);
                    MenuDetail newMenuDetail = new MenuDetail();
                    newMenuDetail.LanguageID = 1;
                    newMenuDetail.MenuID = newMenu.MenuID;
                    newMenuDetail.MenuTitle = temp.ContentTitle;
                    _db.AddToMenuDetail(newMenuDetail);
                }

                // cap nhat content image
                if (hasImage)
                {
                    string contentImage = temp.ContentImage;
                    string[] arrString = contentImage.Split(new char[] { '.' });
                    temp.ContentImage = temp.ContentID.ToString() + "." + arrString[1];
                }

                // them rieng cho du an
                if (isProject)
                {
                    ProjectContent project = new ProjectContent();
                    project.ContentID = temp.ContentID;
                    project.Investor = newContent.Investor;
                    project.Address = newContent.Address;
                    project.Designer = newContent.Designer;
                    project.InHomePage = newContent.InHomePage;
                    _db.AddToProjectContent(project);
                }

                // noi dung tieng Viet
                ContentDetail detail1 = new ContentDetail();
                detail1.ContentID = temp.ContentID;
                detail1.LanguageID = 1;
                detail1.ContentTitle = newContent.ContentTitle;
                detail1.BriefDescription = newContent.BriefDescrip;
                detail1.ContentDetail1 = newContent.ContentDetail;

                // noi dung tieng Anh
                //ContentDetail detail2 = new ContentDetail();
                //detail2.ContentID = temp.ContentID;
                //detail2.LanguageID = 2;
                //detail2.ContentTitle = newContent.ContentTitle2;
                //detail2.BriefDescription = newContent.BriefDescrip2;
                //detail2.ContentDetail1 = newContent.ContentDetail2;

                _db.AddToContentDetail(detail1);
                //_db.AddToContentDetail(detail2);
                _db.SaveChanges();
                _logger.InfoFormat("End AddNewContentFull({0})", parentCode);
            }
            catch (Exception ex)
            {
                _logger.Error(ex);
                throw new ArgumentException(ex.Message);
            }
        }

        public void UpdateContentFull(Content updateContent, bool updateMenu, string link, bool isProject)
        {
            try
            {
                _logger.InfoFormat("Begin UpdateContentFull({0})", updateContent.ContentID);
                Content oldContent = _db.Content.FirstOrDefault(b => b.ContentID == updateContent.ContentID);

                if (oldContent == null)
                {
                    _logger.ErrorFormat("There is no content has id = {0}", updateContent.ContentID);
                    return;
                }

                // cap nhat content
                // kiem tra content code da ton tai chua
                bool checkExistCode = true;
                do
                {
                    Content checkContent = GetContentByCode(updateContent.ContentCode);
                    if (checkContent != null && oldContent.ContentCode != updateContent.ContentCode)
                    {
                        updateContent.ContentCode += "-1";
                        _logger.InfoFormat("New content code is ({0})", updateContent.ContentCode);
                    }
                    else
                        checkExistCode = false;
                } while (checkExistCode);
                oldContent.ContentCode = updateContent.ContentCode;
                if (!string.IsNullOrEmpty(updateContent.ContentImage))
                    oldContent.ContentImage = updateContent.ContentImage;

                // cap nhat menu
                if (updateMenu)
                {
                    Menu udpateMenu = _db.Menu.FirstOrDefault(b => b.ContentID == updateContent.ContentID);
                    udpateMenu.MenuLink = link + updateContent.ContentCode;

                    MenuDetail updateMenuDetail = _db.MenuDetail.FirstOrDefault(b => b.LanguageID == 1 && b.MenuID == udpateMenu.MenuID);
                    updateMenuDetail.MenuTitle = updateContent.ContentTitle;
                }

                if (isProject)
                {
                    // noi dung rieng cho du an
                    ProjectContent project = _db.ProjectContent.FirstOrDefault(b => b.ContentID == updateContent.ContentID);
                    if (project == null)
                    {
                        project = new ProjectContent();
                        project.ContentID = updateContent.ContentID;
                        _db.AddToProjectContent(project);
                    }
                    project.Address = updateContent.Address;
                    project.Designer = updateContent.Designer;
                    project.Investor = updateContent.Investor;
                    project.InHomePage = updateContent.InHomePage;
                }


                // noi dung tieng Viet
                ContentDetail detail1 = _db.ContentDetail.FirstOrDefault(b =>
                    b.ContentID == updateContent.ContentID && b.LanguageID == 1);
                if (detail1 != null)
                {
                    detail1.ContentTitle = updateContent.ContentTitle;
                    detail1.BriefDescription = updateContent.BriefDescrip;
                    detail1.ContentDetail1 = updateContent.ContentDetail;
                }
                else
                    _logger.WarnFormat("There is no content detail which has id = {0} and languageId = 1)", updateContent.ContentID);

                // noi dung tieng Anh
                //ContentDetail detail2 = _db.ContentDetail.FirstOrDefault(b =>
                //    b.ContentID == updateContent.ContentID && b.LanguageID == 2);
                //if (detail2 == null)
                //{
                //    _logger.WarnFormat("There is no content detail which has id = {0} and languageId = 2)", updateContent.ContentID);
                //    detail2 = new ContentDetail();
                //    detail2.ContentID = updateContent.ContentID;
                //    detail2.LanguageID = 2;
                //}

                //detail2.ContentTitle = updateContent.ContentTitle2;
                //detail2.BriefDescription = updateContent.BriefDescription2;
                //detail2.ContentDetail1 = updateContent.ContentDetail2;
                //if (detail2 == null)
                //    _db.AddToContentDetail(detail2);

                _db.SaveChanges();
                _logger.InfoFormat("End UpdateContentFull({0})", updateContent.ContentID);
            }
            catch (Exception ex)
            {
                _logger.Error(ex);
                throw new ArgumentException(ex.Message);
            }
        }

        public string DeleteContentsByListId(string lstId, bool isProject, bool deleteMenu)
        {
            try
            {
                _logger.InfoFormat("Begin DeleteContentsByListId({0})", lstId);
                string result = string.Empty;
                string[] arr = lstId.Split('-');

                foreach (string id in arr)
                {
                    if (id.Length > 0)
                    {
                        int idDelete = int.Parse(id);
                        Content deleteContent = _db.Content.FirstOrDefault(b => b.ContentID == idDelete);
                        if (deleteContent != null)
                        {
                            result = deleteContent.ContentImage;
                            ContentDetail detail = _db.ContentDetail.FirstOrDefault(b => b.ContentID == idDelete
                                && b.LanguageID == 1);
                            if (detail != null)
                                _db.DeleteObject(detail);
                            detail = _db.ContentDetail.FirstOrDefault(b => b.ContentID == idDelete
                                && b.LanguageID == 2);
                            if (detail != null)
                                _db.DeleteObject(detail);

                            if (isProject)
                            {
                                ProjectContent project = _db.ProjectContent.FirstOrDefault(b => b.ContentID == idDelete);
                                if (project != null)
                                    _db.DeleteObject(project);
                            }

                            _db.DeleteObject(deleteContent);

                            if (deleteMenu)
                            {
                                Menu menu = _db.Menu.FirstOrDefault(b => b.ContentID == deleteContent.ContentID);
                                MenuDetail menuDetail = _db.MenuDetail.FirstOrDefault(b => b.LanguageID == 1 && b.MenuID == menu.MenuID);
                                _db.DeleteObject(menuDetail);
                                _db.DeleteObject(menu);
                            }
                        }
                    }
                }

                _db.SaveChanges();
                _logger.InfoFormat("End DeleteContentsByListId({0})", lstId);

                return result;
            }
            catch (Exception ex)
            {
                _logger.Error(ex);
                throw new ArgumentException(ex.Message);
            }
        }

        public List<int> GetChildIDByParent(List<int> parentIDs)
        {
            try
            {
                _logger.Info("Begin GetChildIDByParent()");
                List<int> result = new List<int>();
                foreach (int parentID in parentIDs)
                {
                    var childIDs = from b in _db.Content
                                   where b.ContentParent == parentID
                                   select b.ContentID;

                    foreach (int id in childIDs)
                        result.Add(id);
                }

                _logger.Info("End GetChildIDByParent()");

                return result;
            }
            catch (Exception ex)
            {
                _logger.Error(ex);
                throw new ArgumentException(ex.Message);
            }
        }
    }
}
